package com.sp.business.normalization.impl.mf2;

import java.util.ArrayList;
import java.util.List;

import com.sp.business.objectmodel.NormalizedData;
import com.sp.generated.xml.firemon.AddressTranslationMethodProperty;
import com.sp.generated.xml.firemon.AddressTranslationMethods;
import com.sp.generated.xml.firemon.Member;
import com.sp.generated.xml.firemon.MemberCollection;
import com.sp.generated.xml.firemon.NATRule;
import com.sp.generated.xml.firemon.NatColumn;
import com.sp.generated.xml.firemon.ServiceObject;
import com.sp.generated.xml.firemon.TranslatedColumn;

/**
 * ExpressionBuilder for NATRules. For explanation see:
 * 
 * http://martinfowler.com/bliki/ExpressionBuilder.html
 * 
 * @author mtaylor
 */
public class NATRuleBuilder {
    private NATRule natRule;
    private List<Object> sourceList;
    private List<Object> sourceTransList;
    private List<Object> destList;
    private List<Object> destTransList;
    private List<Object> serviceList;
    private List<Object> serviceTransList;

    private NATRuleBuilder() {
        natRule = new NATRule();
        sourceList = new ArrayList<Object>();
        sourceTransList = new ArrayList<Object>();
        destList = new ArrayList<Object>();
        destTransList = new ArrayList<Object>();
        serviceList = new ArrayList<Object>();
        serviceTransList = new ArrayList<Object>();
    }

    public static NATRuleBuilder beginRule(String number) {
        NATRuleBuilder builder = new NATRuleBuilder();
        builder.number(number);
        return builder;
    }

    public NATRule build() {
        // InboundAppliedContext from = new InboundAppliedContext();
        // from.setIsAny(NormalizedData.createBooleanProperty(true));
        // natRule.setFrom(from);
        //
        // OutboundAppliedContext to = new OutboundAppliedContext();
        // to.setIsAny(NormalizedData.createBooleanProperty(true));
        // natRule.setTo(to);

        natRule.setSource(createNATColumn(sourceList));
        natRule.setDestination(createNATColumn(destList));
        natRule.setService(createNATColumn(serviceList));
        natRule.setSourceTranslated(createTranslatedColumn(sourceTransList));
        natRule.setDestinationTranslated(createTranslatedColumn(destTransList));
        natRule.setServiceTranslated(createTranslatedColumn(serviceTransList));

        return natRule;
    }

    private NatColumn createNATColumn(List<Object> list) {
        NatColumn column = new NatColumn();
        MemberCollection mc = new MemberCollection();
        for (Object o : list) {
            Member member = new Member();
            member.setObject(o);
            mc.getMembers().add(member);
        }
        column.setMembers(mc);
        return column;
    }

    private TranslatedColumn createTranslatedColumn(List<Object> list) {
        TranslatedColumn column = new TranslatedColumn();

        AddressTranslationMethodProperty transMethod = new AddressTranslationMethodProperty();
        transMethod.setValue(AddressTranslationMethods.NONE);
        column.setTranslationMethod(transMethod);

        MemberCollection mc = new MemberCollection();
        for (Object o : list) {
            Member member = new Member();
            member.setObject(o);
            mc.getMembers().add(member);
        }
        column.setMembers(mc);
        return column;
    }

    public NATRuleBuilder number(String number) {
        natRule.setNumber(NormalizedData.createIntegerProperty(number));
        return this;
    }

    public NATRuleBuilder disabled(Boolean disabled) {
        natRule.setDisabled(NormalizedData.createBooleanProperty(disabled));
        return this;
    }

    public NATRuleBuilder comment(String comment) {
        natRule.setComment(NormalizedData.createStringProperty(comment));
        return this;
    }

    public NATRuleBuilder addSource(Object source) {
        sourceList.add(source);
        return this;
    }

    public NATRuleBuilder addSourceTrans(Object source) {
        sourceTransList.add(source);
        return this;
    }

    public NATRuleBuilder addDest(Object source) {
        destList.add(source);
        return this;
    }

    public NATRuleBuilder addDestTrans(Object source) {
        destTransList.add(source);
        return this;
    }

    public NATRuleBuilder addService(ServiceObject source) {
        serviceList.add(source);
        return this;
    }

    public NATRuleBuilder addServiceTrans(ServiceObject source) {
        serviceTransList.add(source);
        return this;
    }
}
